package cn.aitrox.ry.service.auth.service.impl;

import cn.aitrox.ry.bean.RespResult;
import cn.aitrox.ry.service.auth.dao.AuthRoleDao;
import cn.aitrox.ry.service.auth.dao.AuthUserRoleDao;
import cn.aitrox.ry.service.auth.dto.role.out.AuthRoleDetailDto;
import cn.aitrox.ry.service.auth.dto.user.role.out.AuthUserRoleDetailDto;
import cn.aitrox.ry.service.auth.entity.AuthRoleEntity;
import cn.aitrox.ry.service.auth.entity.AuthUserRoleEntity;
import cn.aitrox.ry.service.auth.service.AuthRoleService;
import cn.aitrox.ry.service.auth.service.AuthUserRoleService;
import cn.aitrox.ry.util.ArrayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class AuthUserRoleServiceImpl implements AuthUserRoleService {

    @Autowired
    private AuthUserRoleDao authUserRoleDao;

    @Autowired
    private AuthRoleDao authRoleDao;

    @Autowired
    private AuthRoleService authRoleService;

    @Transactional
    @Override
    public RespResult update(Integer userId, List<Integer> roleIds) {

        // 判断角色是否存在
        RespResult respResult = authRoleService.validRoleExist(roleIds);
        if (!respResult._isOk()) {
            return respResult;
        }

        List<AuthUserRoleEntity> userRoleEntityListInDB = authUserRoleDao.findByCondition(new AuthUserRoleEntity(null, userId, null), null);
        List<Integer> roleIdsInDB = userRoleEntityListInDB.stream().map(AuthUserRoleEntity::getRoleId).collect(Collectors.toList());


        // 找出需要删除的角色ID，以及需要增加的角色ID
        List<Integer> roleIdsAdd = roleIds.stream().filter(roleId -> !roleIdsInDB.contains(roleId)).collect(Collectors.toList());
        List<Integer> roleIdsRemove = roleIdsInDB.stream().filter(roleId -> !roleIds.contains(roleId)).collect(Collectors.toList());

        if (!ArrayUtil.isEmpty(roleIdsRemove)) {
            authUserRoleDao.deleteByUserIdRoleIds(userId, roleIdsRemove);
        }

        if (!ArrayUtil.isEmpty(roleIdsAdd)) {
            List<AuthUserRoleEntity> userRoleListAdd = roleIdsAdd.stream().map(roleId -> new AuthUserRoleEntity(null, userId, roleId)).collect(Collectors.toList());
            authUserRoleDao.batchInsert(userRoleListAdd);
        }

        return RespResult.ok();
    }

    @Override
    public RespResult<AuthUserRoleDetailDto> read(Integer userId) {
        List<AuthUserRoleEntity> userRoleEntityListInDB = authUserRoleDao.findByCondition(new AuthUserRoleEntity(null, userId, null), null);
        if (ArrayUtil.isEmpty(userRoleEntityListInDB)) {
            return RespResult.ok(new AuthUserRoleDetailDto(null));
        }

        List<Integer> roleIdsInDB = userRoleEntityListInDB.stream().map(AuthUserRoleEntity::getRoleId).collect(Collectors.toList());
        List<AuthRoleEntity> authRoleEntityList = authRoleDao.findByIds(roleIdsInDB.toArray(), null);
        List<AuthRoleDetailDto> roleDetailList = authRoleEntityList.stream().map(x -> new AuthRoleDetailDto(x.getId(), x.getName(), x.getCreateTime(), x.getUpdateTime(), null)).collect(Collectors.toList());

        return RespResult.ok(new AuthUserRoleDetailDto(roleDetailList));
    }
}
